Core modernization and single-resolve dependency management - #14
Merged
Conversation
Hand-authored status/design doc separated from Doxygen output (docs/build/) and config (docs/Doxyfile, docs/doxygen-awesome-css). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Detailed diff report of core_modernization vs main under docs/design. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every target ran its own `conan install`, so zerr_core and the wrappers that link it could be resolved from different profiles. On macOS that produced a core built at the host SDK's deployment target and wrappers at 10.6, and the mismatch surfaced only as linker warnings. Dependencies are now declared once in the root conanfile.txt and generated into a single build/ folder: core and Max/MSP consume conan_toolchain.cmake, PureData consumes conandeps.mk. Committed profiles (macos, linux, mingw) pin the settings that must agree across targets, and recipe revisions are pinned because both libraries need a ConanCenter revision that supports CMake 4. build.sh gains a `deps` target and now discards any build tree or installed archive configured against a different or older toolchain. A CMakeCache silently ignores a newly passed CMAKE_TOOLCHAIN_FILE -- which is how the pinned deployment target went missing to begin with -- and an existing libzerr_core.a is no proof it was built against the toolchain the wrapper is about to use. Also fixes three wrapper faults found while reviewing the above: - mc.zerr.envelopes~ called object_free() before dsp_setup(), so a bad mode or config argument reached dsp_free() on an un-set-up t_pxobject - both envelopes wrappers leaked the ZerrEnvelopes instance when initialize() failed; zerr_envelopes~ additionally leaked two strdup'd strings on every instantiation, success included - puredata/Makefile's clean guard matched `make clean all`, which then built with the CONAN_* variables empty and produced a cryptic compiler error instead of the intended message Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…olution Resolve conan dependencies once at the repo root
build.sh already selected profiles/mingw for MSYS2/Git Bash hosts, but it never matched what the Windows CI jobs actually do, so the path it advertised did not work: - Pin -G "MinGW Makefiles". Without it CMake picks a Visual Studio generator whenever one is installed and compiles with MSVC against a MinGW toolchain. - Prefer mingw32-make over the MSYS make, as the PureData Windows job does. - Discard a build tree whose cached CMAKE_GENERATOR disagrees. Passing -G to a directory configured by a different generator is a hard CMake error, not a warning, so the existing staleness check had to learn about it. - Compare the cached CMAKE_TOOLCHAIN_FILE against the native path spelling. $TOOLCHAIN comes out of `pwd` as /c/Users/..., while the MSYS layer rewrites the argument to C:/Users/... on its way to a native CMake -- a verbatim compare can never match, and every run would discard the tree and rebuild the core. - Refuse maxmsp on Windows in the target-validation loop rather than inside build_maxmsp, because the dispatcher builds the core library before calling the per-target function. A .mxe64 needs MSVC, whose ABI cannot link a MinGW-built libzerr_core.a. The Windows path is written to CI parity but has not been exercised on real hardware. The branches were verified on macOS with a faked host: profile and generator selection across Darwin/Linux/MINGW/MSYS/CYGWIN, mingw32-make preference and fallback, guard ordering for single and multi-target invocations, and that `-c maxmsp` still cleans. docs/design/dependency-fallbacks.md replaces the USE_SYSTEM_DEPS fallback that was assessed and declined. Rather than an untested second resolve path, it records which non-conan routes are viable and what each one breaks: target names verified against the generated files (conan exposes fftw as fftw::fftw but its libraries as FFTW3::* components, with fftw3f/fftw3l siblings of the double precision target we need), static vs shared, YAML_CPP_STATIC_DEFINE living in two places, the deployment target, and the CMake 4 floor behind the pinned recipe revisions. repo-audit §2.3 is corrected: it claimed improve_deps_manage had been fully re-applied. The superbuild and the system-deps fallback were never ported, both deliberately, and the branch also carries two regressions worth recording. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings 26 commits of core modernization and dependency-management work onto
main. This is a refactor/tooling branch, not a feature branch — no audio algorithm was rewritten.mainis fully contained in this branch, so it merges as a clean fast-forward.71 files, +2,809 / −1,442. The
core/library is a net reduction (40 files, +910 / −1,078) despite gaining documentation.What's in it
C++ modernization in
core/— type vocabulary consolidated intypes.h(Complex/FFTBuffer/SpecBufferdropped in favour ofSamplesandfftw_complex);Pair→SpeakerPair; the stringly-typedModesplit into strongly-typedGenMode/TriggerMode; rawnew/delete→unique_ptr;#define→inline constexprinsidenamespace zerr; raw loops replaced;const/noexceptapplied throughout; metadata boilerplate (name/category/descriptionstatics) removed.Dependency consolidation —
core/,puredata/andmaxmsp/each ran their ownconan install, so three independent profile resolutions could disagree. That is how the core came to be compiled for a different macOS deployment target than the wrappers linked against (libzerr_core.aatminos 15.0inside an external declaringminos 11.0). Now one rootconanfile.txt, one resolve intobuild/, consumed three ways:conan_toolchain.cmakefor core and Max/MSP,conandeps.mkfor PureData. Committed profiles inprofiles/(macos,linux,mingw) make it reproducible, and recipe revisions are pinned because both libraries need a ConanCenter revision that survives CMake 4.build.sh— gained adepstarget, staleness detection that discards any build tree or installed archive configured against a different or older toolchain (aCMakeCachesilently ignores a newly passedCMAKE_TOOLCHAIN_FILE, which is how the deployment-target pin went missing in the first place), and Windows support for MSYS2/MinGW shells.Wrapper fixes —
mc.zerr.envelopes~calledobject_free()beforedsp_setup(), reachingdsp_free()on an un-set-upt_pxobjectfrom any bad mode or config argument; both envelopes wrappers leaked theirZerrEnvelopesoninitialize()failure;zerr_envelopes~leaked twostrdup'd strings on every instantiation;puredata/Makefile's clean guard matchedmake clean alland then built with emptyCONAN_*variables.Docs — Doxygen setup reorganized under
docs/, plus design docs indocs/design/: a repo audit, a project status report, a change comparison report (written at 22 commits, so it predates the dependency work), and a dependency-fallback reference recording which non-conan resolve routes are viable and what each one breaks.Verification
CI dispatched against the branch head: run 32297202438 — macOS, Linux and Windows all green on
75b19d7.Worth noting from that run: macOS and Windows both build fftw and yaml-cpp from source, which is exactly what fails under CMake 4 without the pinned revisions — so the pin is exercised every run, not just theoretically load-bearing. The macOS job logs
CMAKE_OSX_DEPLOYMENT_TARGET set to 10.13, confirming the pin reaches CI.Locally, from a fully clean tree: core at
minos 11.0, 4 PureData externals, 5 Max/MSP externals, no sharedyaml-cpp/fftwin the linked output.Known and deferred — not introduced here
zerr_envelopes_perform64calls aperform()that can throw, so an exception can reachstd::terminatefrom Max's audio thread;EnvelopeGenerator::processFuncis a pointer-to-member read uninitialized, defeating its ownif (processFunc)guard; and the!yaml_foundpath leaks its allocated object.build.shpath is written to CI parity but unexercised on real hardware. CI never invokesbuild.sh. Also,profiles/mingwpinscompiler.version=13while the runners now carry gcc 16.1.0 — it works because thelibstdc++11ABI is stable, but the setting has drifted. Knowingly left open.jack/remains dead code —meson.buildlists ~15 sources that do not exist and the headers reference modules deleted from the core. Untouched by this branch; still advertised in the README.After merge
This is the first push to
mainsince the workflows were rewritten, and all three trigger on push tomain— so merging will fire the core build, the PureData chain that depends on it, and the Doxygen deploy.🤖 Generated with Claude Code